from .log import log_gui
import gtk
import pango
import pygtk
import time
import threading
import gobject
import traceback
from rect import Rect

x=0
def DrawSmallRedRectangle(window, x, y):
  cmap = window.get_colormap()
  color = cmap.alloc_color('#FF0000')
  colorgc = window.new_gc()
  colorgc.set_foreground(color)
  colorgc.set_fill(gtk.gdk.SOLID)

  window.draw_rectangle(
      colorgc, True, x, y, 10, 10)

class BaseScreenWidget:
  def __init__(self, x, y, width, height):
    self.rect = Rect((x, y, width, height))
    self.parent = None

  def screen(self):
    return self.parent

  def Paint(self):
    """Cleanly and atomically paint the whole screen."""
    self.parent.Paint()

  def Draw(self, window, clip_rect):
    pass

  def OnAdd(self, parent):
    self.parent = parent

  def OnButtonDown(self, event, data):
    pass

  def OnButtonUp(self, event, data):
    pass

  def Update(self):
    pass

  def GetWidth(self):
    return self.rect.width

  def GetHeight(self):
    return self.rect.height

class BaseScreen:
  def __init__(self, parent):
    log_gui("BaseScreen called with a parent of", parent)
    self.parent = parent
    self.ignore_clicks = False
    self.clip_rect = None
    self.colorgc = None
    self.backgroundcolor = '#FFFFFF'
    self._base_coords = (0, 0)
    self.InitRect()
    self._widgets = []
    self._button_down_widget = None

  def SetPosition(self, x, y):
    log_gui("Set position of", self, "to",x,y)
    self._base_coords = (x, y)
    self.rect.top = y
    self.rect.left = x

  def SetIgnoreClicks(self, value):
    self.ignore_clicks = value

  def SetClipRect(self, rect):
    log_gui("Set clip of", self, "to", rect)
    if rect:
      self.clip_rect = Rect((rect.left, rect.top, rect.width, rect.height))
    else:
      self.clip_rect = None

  def InitRect(self):
      """Create the widget rectangle used for calculations"""
      w, h = self.parent.size_request()
      self.rect = Rect((self._base_coords[0], self._base_coords[1], w, h))

  def OnUnrealized(self, widget=None, data=None):
      """Call when we are unrealized."""
      for widget in self._widgets:
        widget.OnUnrealized()

  def OnExpose(self, widget=None, event=None, data=None):
    log_gui("Expose")
    self.Paint()

  def Paint(self):
    self.InitRect()

    if not self.rect:
      log_gui("No self.rect, not painting.", self.rect)
      return

    if self.parent.get_style().white_gc == None:
      log_gui("No white gc")
      return

    #log_gui("Paint", self.rect)
    self.window().begin_paint_rect(
        (self.rect.top,
         self.rect.left,
         self.rect.width,
         self.rect.height))

    # Main drawing routine
    self.Draw()
    self.window().end_paint()

  def OnMouseMove(self, widget, event, data=None):
    if self._button_down_widget:
      self._button_down_widget.OnMouseMove(event, data)

  def OnRealize(self, widget=None, event=None, data=None):
      """Triggered when the widget is finally ready to draw"""
      self.Update()
      self.Paint()

  def OnResize(self, widget, event=None, data=None):
    # Force recreation of buffer and size rect
    log_gui("OnResize")
    self.rect = None
    self.image = None
    self.Update()
    self.Paint()

  def Draw(self, window=None):
    #log_gui("Screen.Draw. Drawing these widgets: ", self._widgets)
    if window is None:
      window = self.window()
    for widget in self._widgets:
      widget.Draw(self, window, self.clip_rect)

  def OnButtonDown(self, container_widget, event, data=None):
    if not self.ignore_clicks:
      point = (event.x, event.y)
      for widget in self._widgets:
        if widget.rect.collidepoint(point):
          widget.OnButtonDown(event, data)
          self._button_down_widget = widget
          return

  def OnButtonUp(self, widget, event, data=None):
    if self._button_down_widget:
      point = (event.x, event.y)
      self._button_down_widget.OnButtonUp(event, point)
    self._button_down_widget = None

  def Update(self):
    # Update internal state.
    for widget in self._widgets:
      widget.Update()

  def Add(self, widget):
    self._widgets.append(widget)
    widget.OnAdd(self)

  def window(self):
    return self.parent.window

  def GC(self, window=None):
    if not window:
      window = self.window()
    gc = gtk.gdk.GC(window)
    gc.copy(self.parent.get_style().fg_gc[gtk.STATE_NORMAL])
    return gc

  def app(self):
    return self.parent

